<%@ WebHandler Language="C#" Class="ThumbnailHandler" %>
using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Drawing;
using System.Web.Caching;
using System.Configuration;
using System.Drawing.Imaging;

using Adge.Common;


/// <summary>
/// Summary description for $codebehindclassname$
/// </summary>
[WebService(Namespace = "http://www.adge.edu.cn/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ThumbnailHandler : IHttpHandler
{
	int _width, _height;
	String _path;
	bool _bStretch, _bBevel;
	Thumbnail thumb;

	public void ProcessRequest(HttpContext context)
	{
		Image image;
		String sCacheKey;
		bool bFoundInCache = true; // by default
		// create our COM thumbnail generator
		thumb = new Thumbnail();
		// get width and height
		if (context.Request["Width"] != null)
			_width = Int32.Parse(context.Request["Width"]);
		else
		{
			try { _width = int.Parse(System.Configuration.ConfigurationManager.AppSettings["DefaultWidth"]); }
			catch (ArgumentNullException ex) { _width = 150; }
		}
		if (context.Request["Height"] != null)
			_height = Int32.Parse(context.Request["Height"]);
		else
		{
			try
			{
				_height = int.Parse(ConfigurationManager.AppSettings["DefaultHeight"]);
			}
			catch (Exception ex)
			{
				while (ex != null)
				{
					LogMessage(ex.Message);
					ex = ex.InnerException;
				}
				_height = 150;
			}
		}
		// get path of 'no thumbnail' image
		const String NoThumbFile = "NoThumb.gif"; //"victory.jpg";
		String sNoThumbPath = context.Request.MapPath(
		 context.Request.ApplicationPath.TrimEnd('/') + "/" + NoThumbFile);
		// map requested path
		if (context.Request["oFilePath"] != null)
			_path = context.Request.MapPath(context.Request["oFilePath"]);
		else _path = sNoThumbPath;
		//_path = context.Request.MapPath("/images/OLIMP011.jpg"); //-->for test
		// allow stretch of thumbnails
		_bStretch = (context.Request["AllowStretch"] == "true");
		// bevel thumbnails
		_bBevel = (context.Request["Bevel"] == "true");
		// put parameters for thumbnail requested
		thumb.SetParams(_path, _width, _height, _bStretch, _bBevel);
		// get a reference to the cache object
		Cache MyCache = context.Cache;
		sCacheKey = thumb.GetUniqueThumbName();
		// --- remove from cache when we want to refresh
		bool bRefresh = (context.Request["Refresh"] == "true");
		if (bRefresh)
			MyCache.Remove(sCacheKey);
		if (MyCache[sCacheKey] == null)
		{ // the thumbnail does not exist in cache, create it...
			// Create a bitmap of the thumbnail and show it
			try
			{
				image = thumb.ExtractThumbnail();
				bFoundInCache = false;
			}
			catch (Exception e)
			{
				while (e != null)
				{
					LogMessage(e.Message);
					e = e.InnerException;
				}
				// requested image cannot be loaded, try to load the 'NoThumb' image
				_path = sNoThumbPath;
				thumb.SetParams(_path, _width, _height, _bStretch, false);
				sCacheKey = thumb.GetUniqueThumbName();
				if (MyCache[sCacheKey] == null)
				{
					try
					{
						image = thumb.ExtractThumbnail();
						bFoundInCache = false;
					}
					catch (Exception e2)
					{
						while (e2 != null)
						{
							LogMessage(e2.Message);
							e2 = e2.InnerException;
						}
						return;
					}
				}
				else
				{
					image = (Bitmap)MyCache[sCacheKey];
				}
			} // end catch 
		}
		else
		{ // bitmap is in cache
			image = (Bitmap)MyCache[sCacheKey];
		}
		context.Response.ContentType = "image/Jpeg";
		Thumbnail.SaveImage(image, context.Response.OutputStream, Thumbnail.GetImageCodecInfo(ImageFormat.Jpeg));
		//bitmap.Save(context.Response.OutputStream, ImageFormat.Jpeg);
		//if(bFoundInCache) LogMessage("Found in cache");
		// else LogMessage("NOT Found in cache");
		//cache thumbnail, make it dependent upon the file and thumbnail size
		bool bUseCache = !(ConfigurationManager.AppSettings["UseCache"] == "false");
		if (!bFoundInCache && bUseCache)
		{
			CacheDependency dependency = new CacheDependency(_path);
			int mins; try
			{
				mins = int.Parse(ConfigurationManager.AppSettings["SlidingExpireMinutes"]);
			}
			catch (Exception ex)
			{
				while (ex != null)
				{
					LogMessage(ex.Message);
					ex = ex.InnerException;
				}
				mins = 20;
			}
			MyCache.Insert(sCacheKey, image, dependency,
			   Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(mins),
			   CacheItemPriority.Default, new CacheItemRemovedCallback(RemovedCallback));
			dependency.Dispose();
		}
		// bitmap in cache, dont dispose yet
		//bitmap.Dispose ();
	}

	static public void RemovedCallback(String k, Object item, CacheItemRemovedReason r)
	{
		((Bitmap)item).Dispose();
		//LogMessage("Callback");
	}

	// for custom tracing, normal tracing does not work with WebHandlers
	static void LogMessage(String mess)
	{
		StreamWriter sw = new StreamWriter(HttpContext.Current.Server.MapPath("logs\\ASP.NET_log.txt"), true);
		sw.WriteLine(mess);
		sw.Close();
	}

	public bool IsReusable
	{
		get
		{
			return true;
		}
	}
}